#pragma once

extern "C" {
  #include <lua.h>
  #include <lauxlib.h>
  #include <lualib.h>
}

#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>
#include <Ogre.h>
#include <MyGUI.h>
#include "LuaLink_SceneManager.h"
#include "LuaLink_Gui.h"
#include "LuaLink_Camera.h"
#include "LuaLink_RaySceneQuery.h"
#include "LuaLink_Trace.h"

using namespace luabind;

struct Key {};
struct Mouse {};

class LuaLink
{
protected:
	lua_State* state;
	LuaLink_Trace* trace;
	LuaLink_SceneManager* sceneManager;
	LuaLink_Gui* gui;
	LuaLink_Camera* camera;
	LuaLink_RaySceneQuery* raySceneQuery;
	bool running;
public:
	luabind::object luaOnEachFrame;
	luabind::object luaOnMouseMoved;
	luabind::object luaOnMousePressed;
	luabind::object luaOnMouseReleased;
	luabind::object luaOnKeyPressed;
	luabind::object luaOnKeyReleased;

	LuaLink();
	virtual ~LuaLink(void);
	void bind(void);
	bool doFile(const Ogre::String& file);
	bool isGuiActive();
	bool isRunning();

	void bind(Ogre::SceneManager* smgr, Ogre::RenderWindow* window);
	void bind(MyGUI::Gui* gui);
	void bind(Ogre::Camera* camera);
	void bind(Ogre::RaySceneQuery* raySceneQuery);

	void eachFrame(const Ogre::FrameEvent& evt);
	void mouseMoved(const OIS::MouseEvent& evt);
	void mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
	void mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
	void keyPressed(const OIS::KeyEvent& evt);
	void keyReleased(const OIS::KeyEvent& evt);

	void lua_trace(const char* msg);
	void lua_debug(bool mode);	LuaLink_SceneManager* lua_getSceneManager();
	LuaLink_Gui* lua_getGui();
	LuaLink_Camera* lua_getCamera();
	void lua_stop();

	void lua_onEachFrame(luabind::object obj);
	void lua_onMouseMoved(luabind::object obj);
	void lua_onMousePressed(luabind::object obj);
	void lua_onMouseReleased(luabind::object obj);
	void lua_onKeyPressed(luabind::object obj);
	void lua_onKeyReleased(luabind::object obj);
};
